﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq.Expressions;
using Fuse8.DomainFramework.Domain;

namespace Fuse8.DomainFramework.DataAccess.SqlDatabase
{
	internal static class EntityParameterBuilder<TEntity>
	{
        private static readonly ConcurrentDictionary<string, SqlParameterInfo> _propertyDelegates = new ConcurrentDictionary<string, SqlParameterInfo>();

		public static SqlParameterInfo BuildPropertyDelegate(string propertyName)
		{
			return _propertyDelegates.GetOrAdd(propertyName, s =>
			                                                     {
                                                                     var parameter = Expression.Parameter(typeof(object), "p");
                                                                     Expression expression = Expression.Convert(parameter, typeof(TEntity));
                                                                     expression = Expression.Property(expression, propertyName);
                                                                     return new SqlParameterInfo
                                                                     {
                                                                         GetterDelegate = Expression.Lambda<Func<object, object>>(Expression.Convert(expression, typeof(object)), parameter).Compile(),
                                                                         Name = propertyName
                                                                     };
			                                                     });
		}
	}
}